import cv2
import numpy as np
import pandas as pd
from Tools import Predict, Area, IntersectionArea


class MyTracker:
    trackerID = 1

    def __init__(self, x, y, right, bottom, ID):
        self.x1 = x
        self.y1 = y
        self.x2 = right
        self.y2 = bottom
        self.currentID = ID
        self.checked = True

    def Update(self, x, y, right, bottom):
        self.x1 = x
        self.y1 = y
        self.x2 = right
        self.y2 = bottom

    @staticmethod
    def trackID(detectionList):
        MyTracker.myTrackerList = Predict(MyTracker.myTrackerList, MyTracker.xStep,
                                          0, MyTracker.min_widthX, MyTracker.max_widthX, MyTracker.widthStep,
                                          MyTracker.direct)
        for tracker in MyTracker.myTrackerList:
            if tracker.checked:
                continue
            for detection in detectionList:
                if detection.checked:
                    continue

                intersection = IntersectionArea(tracker.x1, tracker.y1,
                                                tracker.x2, tracker.y2
                                                , detection.x1, detection.y1,
                                                detection.x2, detection.y2)
                intersection = intersection / Area(tracker.x1, tracker.y1,
                                                   tracker.x2, tracker.y2)
                # print("intersection={0}".format(intersection))
                if intersection > MyTracker.areaThreshold:

                    # 索引到目标，更新自己
                    tracker.checked = True
                    detection.checked = True
                    tracker.Update(detection.x1, detection.y1,
                                   detection.x2, detection.y2)
                    if tracker.currentID == -2:
                        tracker.checkTimes = tracker.checkTimes - 1
                        if tracker.checkTimes == 0:
                            tracker.currentID = MyTracker.trackerID
                            detection.currentID = MyTracker.trackerID
                            MyTracker.trackerID = MyTracker.trackerID + 1

                    detection.currentID = tracker.currentID
                else:

                    tracker.checked = False

        # noTrackXList = []
        # for t in MyTracker.myTrackerList:
        #     if not t.checked:
        #         centerx = (t.x1 + t.x2) / 2
        #         noTrackXList.append(centerx)
        mytemp = []
        for val in MyTracker.myTrackerList:
            if not val.checked:
                mytemp.append([val.x1, val.y1, val.x2, val.y2, val.currentID])
        noTrackXDataFrame = pd.DataFrame(mytemp, columns=["x1", "y1", "x2", "y2", "id"])

        for detecttemp in detectionList:
            # 没有索引到，增加新值
            if not detecttemp.checked:
                center_detect = (detecttemp.x1 + detecttemp.x2) / 2
                if noTrackXDataFrame.empty:
                    newTracker = MyTracker(detecttemp.x1, detecttemp.y1,
                                           detecttemp.x2, detecttemp.y2, -2)

                    detecttemp.currentID = -2
                    newTracker.checkTimes = 3
                    MyTracker.myTrackerList.append(newTracker)

                    continue
                noTrackX_X = (noTrackXDataFrame["x1"] + noTrackXDataFrame["x2"]) / 2
                noTrackX_minX = np.min(noTrackX_X)
                noTrackX_maxX = np.max(noTrackX_X)

                if MyTracker.direct == 1:
                    if center_detect < noTrackX_minX:
                        newTracker = MyTracker(detecttemp.x1, detecttemp.y1,
                                               detecttemp.x2, detecttemp.y2, -2)
                        detecttemp.currentID = -2
                        newTracker.checkTimes = 3
                        MyTracker.myTrackerList.append(newTracker)
                else:
                    if center_detect > noTrackX_maxX:
                        newTracker = MyTracker(detecttemp.x1, detecttemp.y1,
                                               detecttemp.x2, detecttemp.y2, -2)
                        detecttemp.currentID = -2
                        newTracker.checkTimes = 3
                        MyTracker.myTrackerList.append(newTracker)

        mytemp = []
        for val in detectionList:
            if not val.checked:
                mytemp.append([val.x1, val.y1, val.x2, val.y2, val.currentID])
        detectioinDataFrame = pd.DataFrame(mytemp, columns=["x1", "y1", "x2", "y2", "id"])

        if MyTracker.direct == 1:
            detectioinDataFrame = detectioinDataFrame.sort_values(by="x1", ascending=False)
            noTrackXDataFrame = noTrackXDataFrame.sort_values(by="x1", ascending=False)
        else:
            detectioinDataFrame = detectioinDataFrame.sort_values(by="x1", ascending=True)
            noTrackXDataFrame = noTrackXDataFrame.sort_values(by="x1", ascending=True)

        for tup in zip(detectioinDataFrame["x1"], detectioinDataFrame["y1"], detectioinDataFrame["x2"],
                       detectioinDataFrame["y2"], detectioinDataFrame["id"]):
            if noTrackXDataFrame.empty:
                break
            if MyTracker.direct == 1:
                conA = (noTrackXDataFrame["x1"] + noTrackXDataFrame["x2"]) < tup[0] + tup[2]
                conB = noTrackXDataFrame["y1"] + noTrackXDataFrame["y2"] > tup[1] + tup[3] - 15
                conC = noTrackXDataFrame["y1"] + noTrackXDataFrame["y2"] < tup[1] + tup[3] + 15
                temp = noTrackXDataFrame.where(conA & conB & conC)
            else:
                conA = (noTrackXDataFrame["x1"] + noTrackXDataFrame["x2"]) > tup[0] + tup[2]
                conB = noTrackXDataFrame["y1"] + noTrackXDataFrame["y2"] > tup[1] + tup[3] - 15
                conC = noTrackXDataFrame["y1"] + noTrackXDataFrame["y2"] < tup[1] + tup[3] + 15
                temp = noTrackXDataFrame.where(conA & conB & conC)
            temp = temp.dropna(axis=0, how='any')
            if temp.empty:
                break
            kk = temp.head(1)
            # print("temp={0}".format(temp))
            kktemp = kk.values.tolist()
            noTrackXDataFrame = noTrackXDataFrame.drop(kk.index[0])
            for tracker in MyTracker.myTrackerList:
                if tracker.checked:
                    continue
                # print(tracker.x1)
                # print(kktemp[0][2])
                if tracker.x1 == kktemp[0][0] and tracker.y1 == kktemp[0][1] and tracker.x2 == kktemp[0][2] and tracker.y2 == kktemp[0][3]:
                    # 索引到目标，更新自己
                    tracker.checked = True
                    detection.checked = True
                    tracker.Update(tup[0], tup[1],
                                   tup[2], tup[3])

        return detectionList
